package rankUtil

import (
	"time"
)

//基础排名项
type BaseRankItem struct {
	// 排名
	Rank int32 `gorm:"-"`

	// 排名使用的值
	Value1 int64 `gorm:"-"`

	// 排名使用的值2
	Value2 int64 `gorm:"-"`

	// 排名值改变时间
	ValueChangeTime time.Time `gorm:"-"`

	// 排名项的唯一Id
	RankId string `gorm:"-"`

	// 实际排名对象
	Object interface{} `gorm:"-" json:"-"`

	// 排行榜中当前排名的上一项
	PreviousRankItem *BaseRankItem `gorm:"-" json:"-"`

	// 排行榜中当前排名的下一项
	NextRankItem *BaseRankItem `gorm:"-" json:"-"`

	// 是否是复制的排名数据
	IsCopy bool `gorm:"-" json:"-"`
}

// 创建一个空的排名项
// 返回：
//		排名项
func NewEmptyBaseRankItem() *BaseRankItem {
	return &BaseRankItem{}
}

// 克隆排名项，克隆没有上下项
// 返回：
//		克隆的排名项
func (this *BaseRankItem) Clone() *BaseRankItem {
	//result := &BaseRankItem{}
	result := getRankItemFromPool()
	result.IsCopy = true
	result.Rank = this.Rank
	result.Value1 = this.Value1
	result.Value2 = this.Value2
	result.ValueChangeTime = this.ValueChangeTime
	result.RankId = this.RankId
	result.Object = this.Object
	//result.PreviousRankItem = this.PreviousRankItem
	//result.NextRankItem = this.NextRankItem

	return result
}

// 与上一项交换位置
func (this *BaseRankItem) ExchangeWithPrevious() {
	this.exchangeBWithC(this.PreviousRankItem.PreviousRankItem, this.PreviousRankItem, this, this.NextRankItem)
}

// 与下一项交换位置
func (this *BaseRankItem) ExchangeWithNext() {
	this.exchangeBWithC(this.PreviousRankItem, this, this.NextRankItem, this.NextRankItem.NextRankItem)
}

// 交换B和C
// 参数：
//		itemA：A项
//		itemB：B项
//		itemC：C项
//		itemD：D项
func (this *BaseRankItem) exchangeBWithC(itemA, itemB, itemC, itemD *BaseRankItem) {
	//列表内容：A[4] B[3] C[2] D[1]
	//当前关系：[]A[B] [A]B[C] [B]C[D] [C]D[]
	// B与C交换
	//交换后：  []A[C] [A]C[B] [C]B[D] [B]D[]

	//#region 交换前段

	//A的下一项从B变成C
	if itemA != nil {
		itemA.NextRankItem = itemC
	}

	//C的上一项从B变成A
	itemC.PreviousRankItem = itemA

	//#endregion

	//#region 交换中段

	//记录B的排名
	var itemBRank = itemB.Rank

	//设置B的排名为C的排名
	itemB.Rank = itemC.Rank
	//B的上一项从A变为C
	itemB.PreviousRankItem = itemC

	//C的下一项从D变为B
	itemC.NextRankItem = itemB

	//设置C的排名为B的排名
	itemC.Rank = itemBRank

	//#endregion

	//#region 交换后段

	//D的上一项从C变成B
	if itemD != nil {
		itemD.PreviousRankItem = itemB
	}
	//B的下一项从C变成D
	itemB.NextRankItem = itemD

	//#endregion
}
